using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TowerDefense.model;

namespace TowerDefense
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont OutputFont;
        float Fps = 0f;
        private const int NumberSamples = 50; //Update fps timer based on this number of samples
        int[] Samples = new int[NumberSamples];
        int CurrentSample = 0;
        int TicksAggregate = 0;
        int SecondSinceStart = 0;

        private Texture2D cursorTex;
        private Texture2D wallTexture;
        private Vector2 cursorPos;
        private TowerDefenseClass TowerDefenseGame;
        private MouseState mouseState, previousMouseState;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            base.Initialize();
            graphics.SynchronizeWithVerticalRetrace = false;
            IsMouseVisible = true;
            int DesiredFrameRate = 60;
            TargetElapsedTime = new TimeSpan(TimeSpan.TicksPerSecond / DesiredFrameRate);
            graphics.ToggleFullScreen();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            TowerDefenseGame = new TowerDefenseClass();
            OutputFont = Content.Load<SpriteFont>("calibri");
            cursorTex = Content.Load<Texture2D>("mouse_cursor");
            wallTexture = Content.Load<Texture2D>("wall");

        }

        protected override void UnloadContent()
        {/* Nothing to do */}

        int lastXClicked = 0;
        int lastYClicked = 0;
        protected override void Update(GameTime gameTime)
        {
            mouseState = Mouse.GetState();

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
                this.Exit();

            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                int x = (int)(mouseState.X / TowerDefenseClass.SIZE_PER_TILE);
                int y = (int)(mouseState.Y / TowerDefenseClass.SIZE_PER_TILE);
                if (x < TowerDefenseClass.ARRAY_SIZE && y < TowerDefenseClass.ARRAY_SIZE)
                {


                    Building building = new WallBuilding(x, y);
                    TowerDefenseGame.tilesArray[x, y] = new Tile();
                    building.Tile = TowerDefenseGame.tilesArray[x, y];
                    TowerDefenseGame.tilesArray[x, y].Building = building;
                    TowerDefenseGame.tilesArray[x, y].IsUsed = true;
                }

                lastXClicked = x;
                lastYClicked = y;
            }


            cursorPos = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

            previousMouseState = mouseState;

            base.Update(gameTime);
        }

        private float Sum(int[] Samples)
        {
            float RetVal = 0f;
            for (int i = 0; i < Samples.Length; i++)
            {
                RetVal += (float)Samples[i];
            }
            return RetVal;
        }

        private Color ClearColor = Color.FromNonPremultiplied(20, 20, 40, 255);
        protected override void Draw(GameTime gameTime)
        {
            Samples[CurrentSample++] = (int)gameTime.ElapsedGameTime.Ticks;
            TicksAggregate += (int)gameTime.ElapsedGameTime.Ticks;
            if (TicksAggregate > TimeSpan.TicksPerSecond)
            {
                TicksAggregate -= (int)TimeSpan.TicksPerSecond;
                SecondSinceStart += 1;
            }
            if (CurrentSample == NumberSamples) //We are past the end of the array since the array is 0-based and NumberSamples is 1-based
            {
                float AverageFrameTime = Sum(Samples) / NumberSamples;
                Fps = TimeSpan.TicksPerSecond / AverageFrameTime;
                CurrentSample = 0;
            }

            MouseState state = Mouse.GetState();

            GraphicsDevice.Clear(ClearColor);
            spriteBatch.Begin();
            if (Fps > 0)
            {
                spriteBatch.DrawString(OutputFont, string.Format("Current FPS: {0}\nMouseX,Y: {1},{2}\nX,Y : {3},{4}", Fps.ToString("000"), 
                    state.X, state.Y,
                    lastXClicked, lastYClicked)
                    , new Vector2(10, 10), Color.White);
            }

            for (int x = 0; x < TowerDefenseClass.ARRAY_SIZE; x++)
            {
                for (int y = 0; y < TowerDefenseClass.ARRAY_SIZE; y++)
                {
                    if (TowerDefenseGame.tilesArray[x, y] != null && TowerDefenseGame.tilesArray[x, y].Building is WallBuilding)
                    {
                        Vector2 v = TowerDefenseGame.tilesArray[x, y].Building.Vector;
                        spriteBatch.Draw(wallTexture, new Vector2(v.X * TowerDefenseClass.SIZE_PER_TILE, v.Y * TowerDefenseClass.SIZE_PER_TILE), Color.White);
                    }
                }
            }

            //spriteBatch.Draw(cursorTex, cursorPos, Color.White);

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
